gfloat x_origin;
gfloat y_origin;
- ClutterInputDevice *grab_device;
- ClutterGrab *grab;
-
ClutterActor *trough;
ClutterActor *handle;
gfloat move_x;
gfloat move_y;
+ ClutterPanGesture *trough_pan_gesture;
+ ClutterPanGesture *handle_pan_gesture;
+
/* Trough-click handling. */
enum { NONE, UP, DOWN } paging_direction;
guint paging_source_id;
static guint signals[LAST_SIGNAL] = { 0, };
-static gboolean
-handle_button_press_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- StScrollBar *bar);
-
-static void stop_scrolling (StScrollBar *bar);
-
ClutterOrientation
st_scroll_bar_get_orientation (StScrollBar *bar)
{
static void
st_scroll_bar_unmap (ClutterActor *actor)
{
- CLUTTER_ACTOR_CLASS (st_scroll_bar_parent_class)->unmap (actor);
+ StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (ST_SCROLL_BAR (actor));
+
+ if (priv->handle)
+ clutter_gesture_cancel (CLUTTER_GESTURE (priv->handle_pan_gesture));
- stop_scrolling (ST_SCROLL_BAR (actor));
+ CLUTTER_ACTOR_CLASS (st_scroll_bar_parent_class)->unmap (actor);
}
static void
st_adjustment_set_value (priv->adjustment, position);
}
-static void
-stop_scrolling (StScrollBar *bar)
-{
- StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (bar);
- if (!priv->grab_device)
- return;
-
- st_widget_remove_style_pseudo_class (ST_WIDGET (priv->handle), "active");
-
- if (priv->grab)
- {
- clutter_grab_dismiss (priv->grab);
- g_clear_object (&priv->grab);
- }
-
- priv->grab_device = NULL;
- g_signal_emit (bar, signals[SCROLL_STOP], 0);
-}
-
-static gboolean
-handle_motion_event_cb (ClutterActor *trough,
- ClutterEvent *event,
- StScrollBar *bar)
-{
- StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (bar);
- graphene_point_t coords;
-
- if (!priv->grab_device)
- return FALSE;
-
- clutter_event_get_position (event, &coords);
- move_slider (bar, coords.x, coords.y);
- return TRUE;
-}
-
-static gboolean
-handle_button_release_event_cb (ClutterActor *trough,
- ClutterEvent *event,
- StScrollBar *bar)
-{
- if (clutter_event_get_button (event) != 1)
- return FALSE;
-
- stop_scrolling (bar);
- return TRUE;
-}
-
-static gboolean
-handle_button_press_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- StScrollBar *bar)
-{
- StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (bar);
- ClutterInputDevice *device = clutter_event_get_device (event);
- graphene_point_t coords;
- ClutterActor *stage;
-
- if (clutter_event_get_button (event) != 1)
- return FALSE;
-
- clutter_event_get_position (event, &coords);
-
- if (!clutter_actor_transform_stage_point (priv->handle,
- coords.x,
- coords.y,
- &priv->x_origin,
- &priv->y_origin))
- return FALSE;
-
- st_widget_add_style_pseudo_class (ST_WIDGET (priv->handle), "active");
-
- /* Account for the scrollbar-trough-handle nesting. */
- priv->x_origin += clutter_actor_get_x (priv->trough);
- priv->y_origin += clutter_actor_get_y (priv->trough);
-
- g_assert (!priv->grab_device);
-
- stage = clutter_actor_get_stage (actor);
- priv->grab = clutter_stage_grab (CLUTTER_STAGE (stage), priv->handle);
- priv->grab_device = device;
- g_signal_emit (bar, signals[SCROLL_START], 0);
-
- return TRUE;
-}
-
static gboolean
trough_paging_cb (StScrollBar *self)
{
return ret;
}
-static gboolean
-trough_button_press_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- StScrollBar *self)
+static void
+trough_pan_recognize_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
{
- StScrollBarPrivate *priv;
- graphene_point_t coords;
-
- g_return_val_if_fail (self, FALSE);
-
- if (clutter_event_get_button (event) != 1)
- return FALSE;
+ StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (self);
+ graphene_point_t centroid;
- priv = st_scroll_bar_get_instance_private (self);
- if (priv->adjustment == NULL)
- return FALSE;
+ if (!priv->adjustment)
+ return;
- clutter_event_get_position (event, &coords);
+ clutter_pan_gesture_get_centroid_abs (pan_gesture, ¢roid);
- priv->move_x = coords.x;
- priv->move_y = coords.y;
+ priv->move_x = centroid.x;
+ priv->move_y = centroid.y;
priv->paging_direction = NONE;
priv->paging_event_no = 0;
trough_paging_cb (self);
-
- return TRUE;
}
-static gboolean
-trough_button_release_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- StScrollBar *self)
+static void
+trough_pan_end_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
{
StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (self);
- if (clutter_event_get_button (event) != 1)
- return FALSE;
+ g_clear_handle_id (&priv->paging_source_id, g_source_remove);
+}
+
+static void
+trough_pan_cancel_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
+{
+ StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (self);
g_clear_handle_id (&priv->paging_source_id, g_source_remove);
+}
- return TRUE;
+static void
+handle_pan_recognize_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
+{
+ StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (self);
+ graphene_point_t centroid;
+
+ clutter_pan_gesture_get_centroid_abs (pan_gesture, ¢roid);
+ if (!clutter_actor_transform_stage_point (priv->handle, centroid.x, centroid.y, ¢roid.x, ¢roid.y))
+ return;
+
+ priv->x_origin = centroid.x;
+ priv->y_origin = centroid.y;
+
+ st_widget_add_style_pseudo_class (ST_WIDGET (priv->handle), "active");
+
+ /* Account for the scrollbar-trough-handle nesting. */
+ priv->x_origin += clutter_actor_get_x (priv->trough);
+ priv->y_origin += clutter_actor_get_y (priv->trough);
+
+ g_signal_emit (self, signals[SCROLL_START], 0);
}
-static gboolean
-trough_leave_event_cb (ClutterActor *actor,
- ClutterEvent *event,
- StScrollBar *self)
+static void
+handle_pan_update_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
+{
+ graphene_point_t centroid;
+
+ clutter_pan_gesture_get_centroid_abs (pan_gesture, ¢roid);
+ move_slider (self, centroid.x, centroid.y);
+}
+
+static void
+handle_pan_end_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
{
StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (self);
- if (priv->paging_source_id)
- {
- g_clear_handle_id (&priv->paging_source_id, g_source_remove);
- return TRUE;
- }
+ st_widget_remove_style_pseudo_class (ST_WIDGET (priv->handle), "active");
+ g_signal_emit (self, signals[SCROLL_STOP], 0);
+}
- return FALSE;
+static void
+handle_pan_cancel_cb (ClutterPanGesture *pan_gesture,
+ StScrollBar *self)
+{
+ StScrollBarPrivate *priv = st_scroll_bar_get_instance_private (self);
+
+ st_widget_remove_style_pseudo_class (ST_WIDGET (priv->handle), "active");
+ g_signal_emit (self, signals[SCROLL_STOP], 0);
}
static void
clutter_actor_set_name (CLUTTER_ACTOR (priv->trough), "trough");
clutter_actor_add_child (CLUTTER_ACTOR (self),
CLUTTER_ACTOR (priv->trough));
- g_signal_connect (priv->trough, "button-press-event",
- G_CALLBACK (trough_button_press_event_cb), self);
- g_signal_connect (priv->trough, "button-release-event",
- G_CALLBACK (trough_button_release_event_cb), self);
- g_signal_connect (priv->trough, "leave-event",
- G_CALLBACK (trough_leave_event_cb), self);
+
+ priv->trough_pan_gesture = CLUTTER_PAN_GESTURE (clutter_pan_gesture_new ());
+ clutter_pan_gesture_set_begin_threshold (priv->trough_pan_gesture, 0);
+ clutter_actor_meta_set_name (CLUTTER_ACTOR_META (priv->trough_pan_gesture),
+ "StScrollBar trough pan");
+
+ g_signal_connect (priv->trough_pan_gesture, "recognize",
+ G_CALLBACK (trough_pan_recognize_cb), self);
+ g_signal_connect (priv->trough_pan_gesture, "end",
+ G_CALLBACK (trough_pan_end_cb), self);
+ g_signal_connect (priv->trough_pan_gesture, "cancel",
+ G_CALLBACK (trough_pan_cancel_cb), self);
+
+ clutter_actor_add_action (CLUTTER_ACTOR (priv->trough), CLUTTER_ACTION (priv->trough_pan_gesture));
priv->handle = (ClutterActor *) g_object_new (ST_TYPE_WIDGET, NULL);
st_widget_set_track_hover (ST_WIDGET (priv->handle), TRUE);
st_widget_set_style_class_name (ST_WIDGET (priv->handle), "hhandle");
clutter_actor_add_child (CLUTTER_ACTOR (self),
CLUTTER_ACTOR (priv->handle));
- g_signal_connect (priv->handle, "button-press-event",
- G_CALLBACK (handle_button_press_event_cb), self);
- g_signal_connect (priv->handle, "button-release-event",
- G_CALLBACK (handle_button_release_event_cb), self);
- g_signal_connect (priv->handle, "motion-event",
- G_CALLBACK (handle_motion_event_cb), self);
+
+ priv->handle_pan_gesture = CLUTTER_PAN_GESTURE (clutter_pan_gesture_new ());
+ clutter_pan_gesture_set_begin_threshold (priv->handle_pan_gesture, 0);
+ clutter_actor_meta_set_name (CLUTTER_ACTOR_META (priv->handle_pan_gesture),
+ "StScrollBar handle pan");
+
+ g_signal_connect (priv->handle_pan_gesture, "recognize",
+ G_CALLBACK (handle_pan_recognize_cb), self);
+ g_signal_connect (priv->handle_pan_gesture, "pan-update",
+ G_CALLBACK (handle_pan_update_cb), self);
+ g_signal_connect (priv->handle_pan_gesture, "end",
+ G_CALLBACK (handle_pan_end_cb), self);
+ g_signal_connect (priv->handle_pan_gesture, "cancel",
+ G_CALLBACK (handle_pan_cancel_cb), self);
+
+ clutter_actor_add_action (CLUTTER_ACTOR (priv->handle), CLUTTER_ACTION (priv->handle_pan_gesture));
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);